<script setup>
import { ref, computed } from 'vue'
import { useProductStore } from '../stores/04.getters(组合式)'
import { storeToRefs } from 'pinia'

// 获取store实例
const productStore = useProductStore()

// 使用storeToRefs保持响应性
const { products, selectedCategory, priceRange } = storeToRefs(productStore)

// 库存阈值
const stockThreshold = ref(10)

// 计算低库存产品
const lowStockProducts = computed(() => {
  return productStore.lowStockProducts(stockThreshold.value)
})

// 新产品表单
const newProduct = ref({
  name: '',
  price: 0,
  category: '',
  stock: 1
})

// 添加新产品
function addProduct() {
  if (newProduct.value.name && newProduct.value.price > 0 && newProduct.value.category) {
    productStore.addProduct({
      name: newProduct.value.name,
      price: Number(newProduct.value.price),
      category: newProduct.value.category,
      stock: Number(newProduct.value.stock)
    })
    // 重置表单
    newProduct.value = {
      name: '',
      price: 0,
      category: '',
      stock: 1
    }
  }
}

// 价格范围
const minPrice = ref(priceRange.value.min)
const maxPrice = ref(priceRange.value.max)

// 更新价格范围
function updatePriceRange() {
  productStore.setPriceRange(Number(minPrice.value), Number(maxPrice.value))
}

// 重置价格范围
function resetPriceRange() {
  const { min, max } = productStore.priceStats
  minPrice.value = min
  maxPrice.value = max
  productStore.setPriceRange(min, max)
}

// 排序方式
const sortBy = ref('default')

// 根据排序方式获取排序后的产品
const sortedProducts = computed(() => {
  switch (sortBy.value) {
    case 'price-asc':
      return [...productStore.filteredProducts].sort((a, b) => a.price - b.price)
    case 'price-desc':
      return [...productStore.filteredProducts].sort((a, b) => b.price - a.price)
    case 'stock-asc':
      return [...productStore.filteredProducts].sort((a, b) => a.stock - b.stock)
    case 'stock-desc':
      return [...productStore.filteredProducts].sort((a, b) => b.stock - a.stock)
    default:
      return productStore.filteredProducts
  }
})
</script>

<template>
  <div class="tutorial-container">
    <header>
      <h1>04.getters(组合式)</h1>
      <p class="subtitle">学习如何在组合式API中定义和使用getters</p>
      
      <nav class="tutorial-nav">
        <router-link to="/01" class="nav-link">01.认识pinia</router-link>
        <router-link to="/02" class="nav-link">02.定义store(选项式)</router-link>
        <router-link to="/02c" class="nav-link">02.定义store(组合式)</router-link>
        <router-link to="/03" class="nav-link">03.state(选项式)</router-link>
        <router-link to="/03c" class="nav-link">03.state(组合式)</router-link>
        <router-link to="/04" class="nav-link">04.getters(选项式)</router-link>
        <router-link to="/04c" class="nav-link">04.getters(组合式)</router-link>
        <router-link to="/05" class="nav-link">05.actions(选项式)</router-link>
        <router-link to="/05c" class="nav-link">05.actions(组合式)</router-link>
      </nav>
    </header>

    <main>
      <section class="intro">
        <h2>什么是 Getters?</h2>
        <p>Getters 相当于 store 的计算属性。它们可以用来过滤或计算派生状态，并且会缓存结果，只有当依赖的状态发生变化时才会重新计算。</p>
        
        <div class="code-example">
          <pre><code>// 定义一个带有getters的store
export const useStore = defineStore('storeId', {
  state: () => ({
    count: 0,
    users: []
  }),
  getters: {
    // 基本getter
    doubleCount(state) {
      return state.count * 2
    },
    // 使用this访问其他getter
    quadrupleCount() {
      return this.doubleCount * 2
    },
    // 返回一个函数的getter (可接收参数)
    getUserById: (state) => (userId) => {
      return state.users.find(user => user.id === userId)
    }
  }
})</code></pre>
        </div>
      </section>

      <div class="demo-section">
        <div class="products-section">
          <h2>产品管理示例</h2>
          
          <!-- 产品过滤器 -->
          <div class="card">
            <h3>产品过滤器</h3>
            
            <div class="filter-section">
              <div class="filter-group">
                <h4>分类</h4>
                <div class="category-filters">
                  <button 
                    @click="productStore.resetCategoryFilter()" 
                    :class="{ active: !selectedCategory }"
                  >
                    全部
                  </button>
                  <button 
                    v-for="category in productStore.categories" 
                    :key="category"
                    @click="productStore.setCategory(category)"
                    :class="{ active: selectedCategory === category }"
                  >
                    {{ category }}
                  </button>
                </div>
              </div>
              
              <div class="filter-group">
                <h4>价格范围</h4>
                <div class="price-range">
                  <div class="range-inputs">
                    <div class="input-group">
                      <label>最低价格</label>
                      <input v-model="minPrice" type="number" min="0" />
                    </div>
                    <div class="input-group">
                      <label>最高价格</label>
                      <input v-model="maxPrice" type="number" min="0" />
                    </div>
                  </div>
                  <div class="range-actions">
                    <button @click="updatePriceRange" class="btn primary">应用</button>
                    <button @click="resetPriceRange" class="btn secondary">重置</button>
                  </div>
                </div>
              </div>
              
              <div class="filter-group">
                <h4>排序方式</h4>
                <select v-model="sortBy">
                  <option value="default">默认排序</option>
                  <option value="price-asc">价格 (低到高)</option>
                  <option value="price-desc">价格 (高到低)</option>
                  <option value="stock-asc">库存 (低到高)</option>
                  <option value="stock-desc">库存 (高到低)</option>
                </select>
              </div>
            </div>
          </div>
          
          <!-- 产品统计 -->
          <div class="card">
            <h3>产品统计</h3>
            
            <div class="stats-grid">
              <div class="stat-item">
                <h4>产品总数</h4>
                <p class="stat-value">{{ productStore.totalProductsCount }}</p>
              </div>
              <div class="stat-item">
                <h4>总库存</h4>
                <p class="stat-value">{{ productStore.totalStock }}</p>
              </div>
              <div class="stat-item">
                <h4>总价值</h4>
                <p class="stat-value">¥{{ productStore.totalValue.toLocaleString() }}</p>
              </div>
              <div class="stat-item">
                <h4>价格范围</h4>
                <p class="stat-value">¥{{ productStore.priceStats.min }} - ¥{{ productStore.priceStats.max }}</p>
              </div>
              <div class="stat-item">
                <h4>平均价格</h4>
                <p class="stat-value">¥{{ Math.round(productStore.priceStats.avg) }}</p>
              </div>
              <div class="stat-item">
                <h4>低库存产品</h4>
                <p class="stat-value">{{ lowStockProducts.length }}</p>
                <div class="threshold-control">
                  <label>阈值:</label>
                  <input v-model="stockThreshold" type="number" min="1" max="50" />
                </div>
              </div>
            </div>
          </div>
          
          <!-- 产品列表 -->
          <div class="card">
            <h3>产品列表 ({{ sortedProducts.length }})</h3>
            
            <div class="products-list">
              <div v-for="product in sortedProducts" :key="product.id" class="product-item">
                <div class="product-info">
                  <h4>{{ product.name }}</h4>
                  <p>价格: ¥{{ product.price }}</p>
                  <p>分类: {{ product.category }}</p>
                  <p :class="{ 'low-stock': product.stock < stockThreshold }">
                    库存: {{ product.stock }}
                    <span v-if="product.stock < stockThreshold" class="low-stock-badge">
                      低库存
                    </span>
                  </p>
                </div>
                <div class="product-actions">
                  <div class="stock-control">
                    <button 
                      @click="productStore.updateStock(product.id, Math.max(0, product.stock - 1))" 
                      class="btn secondary small"
                      :disabled="product.stock <= 0"
                    >
                      -
                    </button>
                    <span>{{ product.stock }}</span>
                    <button 
                      @click="productStore.updateStock(product.id, product.stock + 1)" 
                      class="btn secondary small"
                    >
                      +
                    </button>
                  </div>
                </div>
              </div>
            </div>
          </div>
          
          <!-- 添加新产品 -->
          <div class="card">
            <h3>添加新产品</h3>
            
            <div class="form-grid">
              <div class="form-group">
                <label>产品名称</label>
                <input v-model="newProduct.name" type="text" placeholder="输入产品名称" />
              </div>
              <div class="form-group">
                <label>价格</label>
                <input v-model="newProduct.price" type="number" min="0" placeholder="输入价格" />
              </div>
              <div class="form-group">
                <label>分类</label>
                <input v-model="newProduct.category" type="text" placeholder="输入分类" list="categories" />
                <datalist id="categories">
                  <option v-for="category in productStore.categories" :key="category" :value="category" />
                </datalist>
              </div>
              <div class="form-group">
                <label>库存</label>
                <input v-model="newProduct.stock" type="number" min="1" placeholder="输入库存" />
              </div>
            </div>
            
            <button @click="addProduct" class="btn primary">添加产品</button>
          </div>
        </div>
      </div>
      
      <section class="explanation">
        <h2>组合式API中使用Getters</h2>
        
        <div class="subsection">
          <h3>1. 基本Getters</h3>
          <p>在组合式API中，getters可以直接从store实例访问，就像访问state一样：</p>
          <div class="code-example">
            <pre><code>import { useStore } from './store'

// 在组件中
export default {
  setup() {
    const store = useStore()
    
    // 直接访问getter
    console.log(store.doubleCount)
    
    return {
      doubleCount: store.doubleCount
    }
  }
}</code></pre>
          </div>
        </div>
        
        <div class="subsection">
          <h3>2. 带参数的Getters</h3>
          <p>如果getter返回一个函数，你可以向它传递参数：</p>
          <div class="code-example">
            <pre><code>import { useStore } from './store'

export default {
  setup() {
    const store = useStore()
    
    // 调用带参数的getter
    const user = store.getUserById(1)
    
    return {
      getUserById: store.getUserById
    }
  }
}</code></pre>
          </div>
        </div>
        
        <div class="subsection">
          <h3>3. 使用storeToRefs</h3>
          <p>与state一样，你可以使用<code>storeToRefs</code>解构getters并保持响应性：</p>
          <div class="code-example">
            <pre><code>import { useStore } from './store'
import { storeToRefs } from 'pinia'

export default {
  setup() {
    const store = useStore()
    
    // 解构getters和state，保持响应性
    const { count, doubleCount } = storeToRefs(store)
    
    return {
      count,
      doubleCount
    }
  }
}</code></pre>
          </div>
        </div>
        
        <div class="subsection">
          <h3>4. 结合Vue的computed</h3>
          <p>你可以将Pinia的getters与Vue的computed结合使用，创建依赖于store状态的本地计算属性：</p>
          <div class="code-example">
            <pre><code>import { useStore } from './store'
import { computed } from 'vue'

export default {
  setup() {
    const store = useStore()
    
    // 创建依赖于store的计算属性
    const isCountEven = computed(() => store.count % 2 === 0)
    
    return {
      isCountEven
    }
  }
}</code></pre>
          </div>
        </div>
      </section>
    </main>
  </div>
</template>

<style scoped>
.tutorial-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

header {
  margin-bottom: 30px;
  border-bottom: 1px solid #eee;
  padding-bottom: 20px;
}

h1 {
  font-size: 2.5rem;
  margin-bottom: 10px;
}

.subtitle {
  font-size: 1.2rem;
  color: #666;
  margin-bottom: 20px;
}

.tutorial-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 20px;
}

.nav-link {
  padding: 8px 15px;
  background-color: #f5f5f5;
  border-radius: 4px;
  text-decoration: none;
  color: #333;
  transition: background-color 0.2s;
}

.nav-link:hover {
  background-color: #e0e0e0;
}

.intro {
  margin-bottom: 40px;
}

.code-example {
  background-color: #f8f8f8;
  border-radius: 6px;
  padding: 15px;
  margin: 15px 0;
  overflow-x: auto;
}

pre {
  margin: 0;
}

code {
  font-family: 'Courier New', monospace;
  font-size: 0.9rem;
}

.demo-section {
  margin-bottom: 40px;
}

.card {
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  padding: 20px;
  margin-bottom: 20px;
}

.filter-section {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.filter-group h4 {
  margin-bottom: 10px;
}

.category-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.category-filters button {
  padding: 6px 12px;
  background-color: #f1f1f1;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.2s;
}

.category-filters button:hover {
  background-color: #e0e0e0;
}

.category-filters button.active {
  background-color: #4CAF50;
  color: white;
}

.price-range {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.range-inputs {
  display: flex;
  gap: 15px;
}

.input-group {
  flex: 1;
}

.range-actions {
  display: flex;
  gap: 10px;
}

.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 20px;
}

.stat-item {
  background-color: #f9f9f9;
  border-radius: 6px;
  padding: 15px;
}

.stat-item h4 {
  margin-bottom: 10px;
  color: #666;
}

.stat-value {
  font-size: 1.5rem;
  font-weight: bold;
  color: #333;
}

.threshold-control {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 10px;
}

.threshold-control input {
  width: 60px;
}

.products-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 20px;
}

.product-item {
  border: 1px solid #eee;
  border-radius: 6px;
  padding: 15px;
}

.product-info {
  margin-bottom: 15px;
}

.product-actions {
  display: flex;
  justify-content: flex-end;
}

.stock-control {
  display: flex;
  align-items: center;
  gap: 10px;
}

.low-stock {
  color: #f44336;
}

.low-stock-badge {
  background-color: #f44336;
  color: white;
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 0.8rem;
  margin-left: 5px;
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 15px;
  margin-bottom: 20px;
}

.form-group {
  margin-bottom: 15px;
}

label {
  display: block;
  margin-bottom: 5px;
  font-weight: 500;
}

input, select {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 1rem;
}

select {
  background-color: white;
}

.btn {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 1rem;
  transition: background-color 0.2s;
}

.btn.primary {
  background-color: #4CAF50;
  color: white;
}

.btn.primary:hover {
  background-color: #3e8e41;
}

.btn.secondary {
  background-color: #f1f1f1;
  color: #333;
}

.btn.secondary:hover {
  background-color: #e0e0e0;
}

.btn.danger {
  background-color: #f44336;
  color: white;
}

.btn.danger:hover {
  background-color: #d32f2f;
}

.btn.small {
  padding: 4px 8px;
  font-size: 0.9rem;
}

.btn:disabled {
  background-color: #cccccc;
  cursor: not-allowed;
}

.explanation {
  margin-top: 40px;
}

.subsection {
  margin-bottom: 30px;
}
</style>
